package data;

import impsoft.scripting.types.ColorSkeltonScriptable;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;

import kevin.kCachedFileLoader;

public class ImageManager {
	public void downloadImage(String url, String filePath) {
		try {
			saveBufferedImage(getBufferedImage(new URL(url)), filePath);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}

	public BufferedImage getBufferedImage(URL url) {
		try {
			return ImageIO.read(new kCachedFileLoader(url).getURL());
		} catch (Exception e) {
			System.out.println("Failed to get image");
			e.printStackTrace();
			return null;
		}
	}

	public String rgbToHex(Color color) {
		return "#" + Integer.toHexString(color.getRGB() & 0x00ffffff);
	}

	public BufferedImage getBufferedImage(String location) {
		try {
			File f = new File(location);
			return ImageIO.read(f);
		} catch (IOException e) {
			System.out.println("Failed to get image");
			e.printStackTrace();
			return null;
		}
	}

	public void saveBufferedImage(BufferedImage img, String fileName) {
		try {
			ImageIO.write(img, "png", new File(fileName));
		} catch (IOException e) {
			System.out.println("Failed to snapshot paint");
			e.printStackTrace();
		}
	}

	public BufferedImage getSubImage(BufferedImage img, Rectangle r) {
		return img.getSubimage(r.x, r.y, r.width, r.height);
	}

	public BufferedImage getScreenshot(Rectangle r, ColorSkeltonScriptable c) {
		return getSubImage(c.theClientScreenGrabber.getDebugBufferedImage(0), r);
	}

	public BufferedImage blurImage(BufferedImage image, Rectangle rectangle) {
		return blurArea(image, rectangle, 10);
	}

	public BufferedImage sharpenImage(BufferedImage image, Rectangle[] rectangles) {
		synchronized (image) {
			for (Rectangle rectangle : rectangles) {
				image = sharpenArea(image, rectangle, 12);
			}
		}

		return image;
	}

	private GraphicsConfiguration getGraphicsConfiguration() {
		return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
	}

	public BufferedImage createCompatibleTranslucentImage(int width, int height) {
		return getGraphicsConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
	}

	public BufferedImage toCompatibleImage(BufferedImage image) {
		if (image.getColorModel().equals(getGraphicsConfiguration().getColorModel())) {
			return image;
		}

		BufferedImage compatibleImage = getGraphicsConfiguration().createCompatibleImage(image.getWidth(),
				image.getHeight(), image.getTransparency());
		Graphics g = compatibleImage.getGraphics();
		g.drawImage(image, 0, 0, null);
		g.dispose();

		return compatibleImage;
	}

	private BufferedImage sharpenArea(BufferedImage image, Rectangle r, int iterations) {
		BufferedImage src = getSubImage(image, r);
		Graphics g = image.getGraphics();

		float[] my_kernel = { .0f, -1.0f, -1.0f, -1.0f, 9.0f, -1.0f, -1.0f, -1.0f, -1.0f };
		ConvolveOp op = new ConvolveOp(new Kernel(3, 3, my_kernel));
		for (int i = 0; i < iterations; ++i) {
			src = op.filter(src, null);
		}

		g.drawImage(src, r.x, r.y, null);
		return image;
	}

	private BufferedImage blurArea(BufferedImage image, Rectangle r, int iterations) {
		BufferedImage src = getSubImage(image, r);
		Graphics g = image.getGraphics();

		float my_kernel[] = { 0.1F, 0.1F, 0.1F, 0.1F, 0.2F, 0.1F, 0.1F, 0.1F, 0.1F };
		ConvolveOp op = new ConvolveOp(new Kernel(3, 3, my_kernel));
		for (int i = 0; i < iterations; i++) {
			src = op.filter(src, null);
		}

		g.drawImage(src, r.x, r.y, null);
		return image;
	}
}